use std::fmt::Display;

use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum FlowState {
    Runing,
    Completed,
    Suspended,
}
impl From<u8> for FlowState {
    #[inline]
    fn from(i: u8) -> Self {
        match i {
            0 => FlowState::Runing,
            1 => FlowState::Completed,
            2 => FlowState::Suspended,
            _ => FlowState::Runing,
        }
    }
}
impl From<FlowState> for u8 {
    #[inline]
    fn from(s: FlowState) -> Self {
        match s {
            FlowState::Runing => 0,
            FlowState::Completed => 1,
            FlowState::Suspended => 2,
        }
    }
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct RunProcess {
    pub id: u64,
    pub wfid: u32,
    pub name: String,
    pub steps: Vec<StepDetail>,
    pub state: FlowState,
    pub curr_step: u8,
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct StepDetail {
    pub id: u8,
    pub name: String,
    pub executors: Vec<Executor>,
    pub state: StepState,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum StepState {
    None,
    Doing,
    Done,
}
#[derive(
    Debug,
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    strum::EnumString,
    strum::Display,
    Serialize,
    Deserialize,
)]
pub enum TaskStatus {
    None,
    Doing,
    Done,
    Back,
    Suspend,
}
impl From<u8> for TaskStatus {
    #[inline]
    fn from(i: u8) -> Self {
        match i {
            0 => TaskStatus::None,
            1 => TaskStatus::Doing,
            2 => TaskStatus::Done,
            3 => TaskStatus::Back,
            4 => TaskStatus::Suspend,
            _ => TaskStatus::None,
        }
    }
}
impl From<TaskStatus> for u8 {
    #[inline]
    fn from(s: TaskStatus) -> Self {
        match s {
            TaskStatus::None => 0,
            TaskStatus::Doing => 1,
            TaskStatus::Done => 2,
            TaskStatus::Back => 3,
            TaskStatus::Suspend => 4,
        }
    }
}
impl From<&TaskStatus> for u8 {
    #[inline]
    fn from(s: &TaskStatus) -> Self {
        match s {
            TaskStatus::None => 0,
            TaskStatus::Doing => 1,
            TaskStatus::Done => 2,
            TaskStatus::Back => 3,
            TaskStatus::Suspend => 4,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Executor {
    pub user_id: u32,
    pub user_name: String,
    pub task_state: TaskStatus,
    pub start_time: Option<String>,
    pub submit_time: Option<String>,
    pub feed_back: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub enum TaskType {
    Doing,
    Done,
    Suspended,
    Completed,
    Manager,
}
impl From<u8> for TaskType {
    #[inline]
    fn from(i: u8) -> Self {
        match i {
            0 => TaskType::Doing,
            1 => TaskType::Done,
            2 => TaskType::Suspended,
            3 => TaskType::Completed,
            4 => TaskType::Manager,
            _ => TaskType::Doing,
        }
    }
}
impl From<TaskType> for u8 {
    #[inline]
    fn from(s: TaskType) -> Self {
        match s {
            TaskType::Doing => 0,
            TaskType::Done => 1,
            TaskType::Suspended => 2,
            TaskType::Completed => 3,
            TaskType::Manager => 4,
        }
    }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub struct FlowRunProps {
    pub wfid: u32,
    pub step_id: u8,
    pub state: FlowState,
    pub version: u8,
}

#[derive(
    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, strum::EnumString, Deserialize, Serialize,
)]
pub enum SubmitType {
    SendNext,
    SendBack,
    TakeBack,
    Suspend,
    Activate,
    Completed,
}
impl Display for SubmitType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            SubmitType::SendNext => write!(f, "提交"),
            SubmitType::SendBack => write!(f, "退回"),
            SubmitType::TakeBack => write!(f, "撤回"),
            SubmitType::Suspend => write!(f, "中止"),
            SubmitType::Activate => write!(f, "激活"),
            SubmitType::Completed => write!(f, "强制完成"),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct TaskDoing {
    pub wfid: u32,
    pub name: String,
    pub count: u32,
    pub perm_id: u32,
}
